using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
using System.Reflection;
using GersonFrame.ABFrame;
using GersonFrame.Tool;

namespace GersonFrame.UI
{
    public enum PanelType
    {
        GameUIPanel,
        MainPanel,
        StoryPanel,
        LoginPanel,
    }
    public enum InnerViewType
    {
        WaveCountPanel,
        AccountPanel,
        PausePanel,
        RevivePanel,
        TopTips,
        StrengthRecoverPanel,
        HangUpSelectHeroPanel,
        TaskPanel,
        RewardGetPanel,
        SettingPanel,
        RenamePanel,
        HeadIconChange,
        SignPanel,
        Mask,
        FastHangupPanel,
        AchievementPanel,
        CommonHint,
        RankingPanel,
        NewFunctionPanel,
        GetHeroPanel,
        GetGrailPanel,
        BackpackPanel,
        BlackMarketPanel,
        HomeLandHeroSelectPanel,
        MagicBoxPanel,
        ItemInfoPanel,
        GuidePanel,
        BuildingLevelUpPanel,
        WaitWebRespon,
        IAPPanel,
        TipsPanel,
    }

    public class UIManager
    {
        private Camera _UICamera;
        public Camera UICamera
        {
            get
            {
                if (_UICamera == null)
                {
                    _UICamera = GameObject.Find("Cameras/CameraUI").GetComponent<Camera>();
                }
                return _UICamera;
            }
        }


        private Camera _MainCamera;
        public Camera MainCamera
        {
            get
            {
                if (_UICamera == null)
                {
                    _UICamera = GameObject.Find("Cameras/Main Camera").GetComponent<Camera>();
                }
                return _UICamera;
            }
        }

        

        private static UIManager _instance;

        public static UIManager Instance
        {
            get
            {
                if (_instance == null)
                {
                    _instance = new UIManager();
                    _instance.InitView();
                }
                return _instance;
            }
        }


        private string m_viewPrefabPath = "Assets/Prefabs/UI/BaseView/";
        private string m_innerViewPrefabPath = "Assets/Prefabs/UI/InnerView/";


        private UIManager()
        {

        }

        private void InitView()
        {
            foreach (PanelType item in Enum.GetValues(typeof(PanelType)))
            {
                m_ViewBasePathDic.Add(item.ToString(), m_viewPrefabPath + item.ToString());
            }
            foreach (InnerViewType item in Enum.GetValues(typeof(InnerViewType)))
            {
                m_InnerViewPathDic.Add(item.ToString(), m_innerViewPrefabPath + item.ToString());
            }

        }


        private Transform canvasTransform;
        private Transform CanvasTransform
        {
            get
            {
                if (canvasTransform == null)
                {
                    canvasTransform = GameObject.Find("Canvas").transform;
                }
                return canvasTransform;
            }
        }

        /// <summary>
        /// 堆栈里面的VIew
        /// </summary>
        private Dictionary<string, MyViewBase> m_viewDict;//保存所有实例化面板的游戏物体身上的BasePanel组件
        private Stack<MyViewBase> m_viewStack;
        private Dictionary<string, string> m_ViewBasePathDic = new Dictionary<string, string>();

        /// <summary>
        /// 不在堆栈里面的
        /// </summary>
        private Dictionary<string, BaseInnerView> m_innerViewDic = new Dictionary<string, BaseInnerView>();
        private Dictionary<string, string> m_InnerViewPathDic = new Dictionary<string, string>();

        /// <summary>
        /// 把某个页面入栈，  把某个页面显示在界面上
        /// </summary>
        public MyViewBase PushView(string panelType, object param = null)
        {
            if (m_viewStack == null)
                m_viewStack = new Stack<MyViewBase>();

            //判断一下栈里面是否有页面
            if (m_viewStack.Count > 0)
            {
                MyViewBase topPanel = m_viewStack.Peek();
                topPanel.OnPause();
            }

            MyViewBase panel = GetMyView(panelType);
            panel.OnEnter(param);
            m_viewStack.Push(panel);
            return panel;
        }


        /// <summary>
        /// 把某个页面入栈，  把某个页面显示在界面上
        /// </summary>
        public MyViewBase PushView<T>(object param = null) where T : MyViewBase
        {
            string viewtype = ClassTool.Name<T>();
            return this.PushView(viewtype, param);
        }

        /// <summary>
        /// 出栈 ，把页面从界面上移除
        /// </summary>
        public void PopPanel()
        {
            if (m_viewStack == null)
                m_viewStack = new Stack<MyViewBase>();

            if (m_viewStack.Count <= 0) return;

            //关闭栈顶页面的显示
            MyViewBase topPanel = m_viewStack.Pop();
            topPanel.OnExit();

            if (m_viewStack.Count <= 0) return;
            MyViewBase topPanel2 = m_viewStack.Peek();
            topPanel2.OnResume();

        }

        public void PopAll()
        {
            if (m_viewStack == null)
                m_viewStack = new Stack<MyViewBase>();

            if (m_viewStack.Count <= 0) return;

            for (int i = 0; i < m_viewStack.Count; i++)
            {
                MyViewBase topPanel = m_viewStack.Pop();
                topPanel.OnExit();
            }
        }


        /// <summary>
        /// 根据面板类型 得到实例化的面板
        /// </summary>
        /// <returns></returns>
        private MyViewBase GetMyView(string viewName)
        {
            if (m_viewDict == null)
            {
                m_viewDict = new Dictionary<string, MyViewBase>();
            }

            MyViewBase panel = m_viewDict.TryGet(viewName);

            if (panel == null)
            {
                string path = this.m_ViewBasePathDic.TryGet(viewName)+".prefab";
                GameObject instPanel = ObjectManager.Instance.InstantiateObject(path,false,false);
            //    GameObject instPanel = GameObject.Instantiate(Resources.Load(path)) as GameObject;
                instPanel.transform.SetParent(CanvasTransform, false);
                m_viewDict.Add(viewName, instPanel.GetComponent<MyViewBase>());
                return instPanel.GetComponent<MyViewBase>();
            }
            else
            {
                return panel;
            }
        }


        //=========================InnerView============================
        public void ShowView(string viewName, object param=null)
        {
            BaseInnerView view = this.GetInnerView(viewName);
            if (view == null)
            {
                MyDebuger.LogError(" not found innerview " + viewName);
                return;
            }

            view.Show(param);
        }

        public void ShowView<T>(object param = null)
        {
            ShowView(ClassTool.Name<T>(), param);
        }


        public void HideView(string viewName)
        {
            BaseInnerView view = m_innerViewDic.TryGet(viewName);
            if (view == null)
                return;
            view.Hide();
        }


        public void HideView<T>()
        {
            HideView(ClassTool.Name<T>());
        }

        public void HideAllView()
        {
            foreach (var item in m_innerViewDic)
            {
                item.Value.Hide();
            }
        }


        /// <summary>
        /// 根据面板类型 得到实例化的面板
        /// </summary>
        /// <returns></returns>
        private BaseInnerView GetInnerView(string viewName)
        {
            BaseInnerView panel = m_innerViewDic.TryGet(viewName);

            if (panel == null)
            {
                string path = this.m_InnerViewPathDic.TryGet(viewName) + ".prefab";
                GameObject instPanel=  ObjectManager.Instance.InstantiateObject(path,false,false);
                instPanel.transform.SetParent(CanvasTransform, false);
                m_innerViewDic.Add(viewName, instPanel.GetComponent<BaseInnerView>());
                return instPanel.GetComponent<BaseInnerView>();
            }
            else
            {
                return panel;
            }
        }


    }
}